/**************************************************************************************************************
 * @copyright Copyright (c) 2015—2024 Uniorange Internet Design Co., LTD. All rights reserved.
 * @author Uniorange Internet Design Co., LTD.
 *
 * This file is part of the App project. Copyright © Uniorange Internet Design Co., Ltd. All Rights Reserved.
 * Unauthorized copying of this file, via any medium is strictly prohibited Proprietary and confidential.
 *
 **************************************************************************************************************/
package com.jinyu.servicedemo.config;

import com.jinyu.core.codec.Decoder;
import com.jinyu.core.codec.Encoder;
import com.jinyu.core.codec.MyLengthFieldBasedFrameDecoder;
import com.jinyu.core.codec.MyLengthFieldPrepender;
import com.jinyu.servicedemo.client.NettyClient;
import com.jinyu.servicedemo.handler.ClientDispatchHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

/**
 * @author 邱金波
 * @version V0.1
 * @className NettClient
 * @description 完成与服务端的链接
 * @date 2024/09/14 13:44
 */
@Configuration
@ConfigurationProperties("netty.server")
@Data
@Slf4j
public class NettConfig implements ApplicationContextAware, InitializingBean {
    private String host;
    private int port;
    private static ApplicationContext applicationContext;

    private Bootstrap bootstrap;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        NettConfig.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        NioEventLoopGroup workGroup = new NioEventLoopGroup(
                Runtime.getRuntime().availableProcessors() + 1, r -> {
            return new Thread(r, "work-" + System.currentTimeMillis());
        });
        bootstrap = new Bootstrap();
        bootstrap.group(workGroup);
        bootstrap.channel(NioSocketChannel.class);
        ClientDispatchHandler bean = applicationContext.getBean(ClientDispatchHandler.class);
        bean.setBootstrap(bootstrap);
        bootstrap.handler(new ChannelInitializer<NioSocketChannel>() {
            @Override
            protected void initChannel(NioSocketChannel ch) throws Exception {
                //字符串编码器，一定要加在SimpleClientHandler 的上面
                //找到他的管道 增加他的handler
                ch.pipeline().addLast(new IdleStateHandler(0, 0, 5));
                ch.pipeline().addLast(new MyLengthFieldBasedFrameDecoder());
                ch.pipeline().addLast(new Decoder());
                ch.pipeline().addLast(new MyLengthFieldPrepender());
                ch.pipeline().addLast(new Encoder());
                ch.pipeline().addLast(bean);
            }
        });
        for (int i = 0; i < 100; i++) {
            NettyClient nettyClient = new NettyClient(bootstrap, host, port);
            nettyClient.connect(host, port);
        }
    }
}
